﻿using System;
using Word = Microsoft.Office.Interop.Word;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace GesPro
{
    /// <summary>
    /// Classe de génération de rapport permettant de créer des rapport sous format PDF à l'aide d'informations fournit.
    /// Les différentes méthodes se sont inspiré des méthodes proposé en ligne par Microsoft.
    /// Microsoft, 2012. « Comment faire pour automatiser Microsoft Word pour créer un nouveau document à l’aide de Visual C# ». Dans Aide et support. En ligne. http://support.microsoft.com/kb/316384. Consulté le 11 novembre 2012.
    /// </summary>
public class GenerateurRapport
{
   
    private List<Rapport> ListeRapportProjet;
    private List<Rapport> ListeRapportEmploye;
    private Projet Object_Projet;
    private Employe Object_Employe;

    object Object_DontCare = System.Reflection.Missing.Value;

    public GenerateurRapport()
	{
	}

    /// <summary>
    /// Trier en ordre croissant les rapports selon le numéro de semaine et d'année
    /// </summary>
    /// <param name="ListeATrier">Liste de rapport devant être trier.</param>
    public void TrierSectionRapportOrdreSemaine(List<Rapport> ListeATrier)
    {
        IComparer<Rapport> AlgoTriageSection = new AlgorithmeTriageSection();

            ListeATrier.Sort(AlgoTriageSection);
    }

    public class AlgorithmeTriageSection : IComparer<Rapport>
    {
        
        public int Compare(Rapport A, Rapport B)
        {
            int comparaisonAnnee;
            comparaisonAnnee = A.Sections[0].Annee.CompareTo(B.Sections[0].Annee);

            if (comparaisonAnnee == 0)
            {
                if (A.Sections[0].Semaine > B.Sections[0].Semaine)
                {
                    return 1;
                }
                else
                {
                    if (A.Sections[0].Semaine == B.Sections[0].Semaine)
                    {
                        return 0;
                    }
                    else
                    {
                        return -1;
                    }
                }
            }
            else
            {
                return comparaisonAnnee;
            }
        }
    }

    /// <summary>
    /// Générer un rapport de projet sous format PDF.
    /// </summary>
    /// <param name="listeRapportProjet">Liste de rapports associés au projet.</param>
    /// <param name="object_projet">Fiche d'information sur le projet.</param>
    /// <param name="complet">Indicatif afin de savoir si un rapport détaillé est voulu.</param>
    public void CreerRapportProjet(List<Rapport> listeRapportProjet, Projet object_projet, bool complet)
    {
        List<string> ListeEmployes = new List<string>();
        decimal VarHeuresReelles = 0;

        ListeRapportProjet = listeRapportProjet;
        Object_Projet = object_projet;
        List<int> ListeSemaineInscrite = new List<int>();

            Word.Application Object_Application;   // classe interface Microsoft.Office.Interop.Word.Application
            Word.Document Object_Document;  // classe interface Microsoft.Office.Interop.Word.Document

            Object_Application = new Word.Application(); // Créer une nouvelle application Word
            Object_Document = new Word.Document(); // Créer un nouveau document Microsoft Word

            Object_Document = Object_Application.Documents.Add(Object_DontCare, Object_DontCare, Object_DontCare, Object_DontCare); // Ajouter le document à l'application
            Object_Application.Visible = false; // Ne permet pas à l'application Word d'afficher sa présence

            InsererTitreStyle1(Object_Document, "Rapport de projet\n");
            InsererTitreStyle2(Object_Document, "Informations");
            InsererTexte(Object_Document, "Nom : " + Object_Projet.Nom);
            InsererTexte(Object_Document, "Responsable : " + Object_Projet.Responsable);
            InsererTexte(Object_Document, "Heures prévues : " + Object_Projet.Heures.ToString());

            foreach (Rapport rapportProjet in ListeRapportProjet)
            {
                foreach (SectionRapport sectionProjet in rapportProjet.Sections)
                {
                    VarHeuresReelles = VarHeuresReelles + sectionProjet.Heures;
                }
            }

            InsererTexte(Object_Document, "Heures réelles : " + VarHeuresReelles.ToString());
            InsererTexte(Object_Document, "Type : " + Object_Projet.Type.ToString());
            InsererTexte(Object_Document, "Date de livraison : " + Object_Projet.Date);

            if (complet == true)
            {
                InsererTitreStyle2(Object_Document, "Description");
                InsererTexte(Object_Document, Object_Projet.Description);
                InsererTitreStyle2(Object_Document, "Objectifs");
                InsererTexte(Object_Document, Object_Projet.Objectifs); 
            }

            InsererTitreStyle2(Object_Document, "Équipe de travail : ");

            foreach (Rapport rapportProjet in ListeRapportProjet)
            {
                if(!ListeEmployes.Contains(rapportProjet.Employe))
                {
                    InsererTexte(Object_Document, rapportProjet.Employe);
                    ListeEmployes.Add(rapportProjet.Employe);
                }
            }

            // ---------------------------Tâches-----------------------------------

            InsererTitreStyle2(Object_Document, "Tâches");

            ListeSemaineInscrite.Clear();
            foreach (Rapport rapportProjet in ListeRapportProjet)
            {
                foreach (SectionRapport sectionProjet in rapportProjet.Sections)
                {
                    if (!ListeSemaineInscrite.Contains(sectionProjet.Semaine))
                    {
                        InsererTexte(Object_Document, "Semaine : " + sectionProjet.Semaine.ToString());
                        ListeSemaineInscrite.Add(sectionProjet.Semaine);
                    }
                    InsererTexte(Object_Document, "Heures : " + sectionProjet.Heures.ToString());
                    InsererTexte(Object_Document, "\tTâches réalisées : " + sectionProjet.Taches);
                }
            }

                    // ---------------------------Problèmes rencontrés-----------------------------------

                if (complet == true)
                {
                    InsererTitreStyle2(Object_Document, "Problèmes rencontrés");

                    ListeSemaineInscrite.Clear();
                    foreach (Rapport rapportProjet in ListeRapportProjet)
                    {
                        foreach (SectionRapport sectionProjet in rapportProjet.Sections)
                        {
                            if (!ListeSemaineInscrite.Contains(sectionProjet.Semaine))
                            {
                                InsererTexte(Object_Document, "Semaine : " + sectionProjet.Semaine.ToString());
                                ListeSemaineInscrite.Add(sectionProjet.Semaine);
                            }
                            InsererTexte(Object_Document, "\tTâches réalisées : " + sectionProjet.Problemes);
                        }
                    }

                            // ---------------------------Solutions apportées-----------------------------------
                    InsererTitreStyle2(Object_Document, "Solutions apportées");

                    ListeSemaineInscrite.Clear();
                    foreach (Rapport rapportProjet in ListeRapportProjet)
                    {
                        foreach (SectionRapport sectionProjet in rapportProjet.Sections)
                        {
                            if (!ListeSemaineInscrite.Contains(sectionProjet.Semaine))
                            {
                                InsererTexte(Object_Document, "Semaine : " + sectionProjet.Semaine.ToString());
                                ListeSemaineInscrite.Add(sectionProjet.Semaine);
                            }
                            InsererTexte(Object_Document, "\tTâches réalisées : " + sectionProjet.Solutions);
                        }
                    }
                }
                ListeSemaineInscrite.Clear();
                SauvegardeEtQuitte(Object_Application, Object_Document, AccesPreferences.CheminRapportsGeneres() + "\\", Object_Projet.Nom, "Rapport");
    }
    /// <summary>
    /// Générer un rapport d'employé sous format PDF.
    /// </summary>
    /// <param name="listeRapportEmploye">Liste de rapports associés à l'employé.</param>
    /// <param name="object_employe">Fiche d'information sur l'employé.</param>
    /// <param name="complet">Inficatif afin de savoir si un rapport détaillé est voulu.</param>
    /// <param name="type">Type de rapport souhaité (Hebdo,période,complet).</param>
    public void CreerRapportEmploye(List<Rapport> listeRapportEmploye, Employe object_employe, bool complet, int type)
    {
        ListeRapportEmploye = listeRapportEmploye;
        Object_Employe = object_employe;

        TrierSectionRapportOrdreSemaine(ListeRapportEmploye);

        Word.Application Object_Application;   // classe interface Microsoft.Office.Interop.Word.Application
        Word.Document Object_Document;  // classe interface Microsoft.Office.Interop.Word.Document

        Object_Application = new Word.Application(); // Créer une nouvelle application Word
        Object_Document = new Word.Document(); // Créer un nouveau document Microsoft Word

        Object_Document = Object_Application.Documents.Add(Object_DontCare, Object_DontCare, Object_DontCare, Object_DontCare); // Ajouter le document à l'application
        Object_Application.Visible = false; // Ne permet pas à l'application Word d'afficher sa présence

        InsererTitreStyle1(Object_Document, "Rapport d'employé\n");
        InsererTitreStyle2(Object_Document, "Informations");
        InsererTexte(Object_Document, "Nom : " + Object_Employe.Nom);
        InsererTexte(Object_Document, "Titre : " + Object_Employe.Titre);
        InsererTexte(Object_Document, "Numéro/code d’employé : " + Object_Employe.Numero);

        if (complet == true)
            InsererTexte(Object_Document, "Courriel : " + Object_Employe.Courriel);

        InsererTexte(Object_Document, "Numéro de téléphone : " + Object_Employe.Telephone);

        if (complet == true)
            InsererTexte(Object_Document, "Note : " + Object_Employe.Note);

        // ---------------------------Tâches-----------------------------------
        InsererTitreStyle2(Object_Document, "Tâches"); 

        List<int> ListeAnneeInscrite = new List<int>();
        List<int> ListeSemaineInscrite = new List<int>();

        foreach (Rapport rapportProjet in ListeRapportEmploye)
        {
            foreach (SectionRapport sectionEmploye in rapportProjet.Sections)
            {
                if (!ListeAnneeInscrite.Contains(sectionEmploye.Annee))
                {
                    InsererTexte(Object_Document, "Année : " + sectionEmploye.Annee.ToString());
                    ListeAnneeInscrite.Add(sectionEmploye.Annee);
                }

                if (!ListeSemaineInscrite.Contains(sectionEmploye.Semaine))
                {
                    InsererTexte(Object_Document, "Semaine : " + sectionEmploye.Semaine.ToString());
                    ListeSemaineInscrite.Add(sectionEmploye.Semaine);
                }

                InsererTexte(Object_Document, "\tProjet : " + sectionEmploye.Projet);
                InsererTexte(Object_Document, "\t\tHeures : " + sectionEmploye.Heures);

                if (complet == true)
                {
                    InsererTexte(Object_Document, "\t\tTâches réalisées : " + sectionEmploye.Taches);
                    InsererTexte(Object_Document, "\t\tProblèmes rencontrés : " + sectionEmploye.Problemes);
                    InsererTexte(Object_Document, "\t\tSolutions aux problèmes : " + sectionEmploye.Solutions);
                }
            }
        }
        ListeAnneeInscrite.Clear();
        ListeSemaineInscrite.Clear();

        SauvegardeEtQuitte(Object_Application, Object_Document, AccesPreferences.CheminRapportsGeneres() + "\\", Object_Employe.Nom, TypeDeRapportEmploye(type));
    }
    /// <summary>
    /// Inserer du texte dans un document Word en particulier.
    /// </summary>
    /// <param name="Object_Document">Document Word visé.</param>
    /// <param name="texte">Texte à insérer.</param>
    public void InsererTexte(Word.Document Object_Document, string texte)
    {
        Word.Paragraph Object_Paragraphe;
        Object_Paragraphe = Object_Document.Content.Paragraphs.Add(Object_DontCare);
        Word.Range Object_Range = Object_Paragraphe.Range;
        Object_Range.Text = texte;
        Object_Range.set_Style(Microsoft.Office.Interop.Word.WdBuiltinStyle.wdStyleBodyText);
        Object_Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        Object_Paragraphe.Range.InsertParagraphAfter();
    }
    /// <summary>
    /// Insérer un titre de style 1 dans un document Word en particulier.
    /// </summary>
    /// <param name="Object_Document">Document Word visé.</param>
    /// <param name="texte">Titre à insérer.</param>
    public void InsererTitreStyle1(Word.Document Object_Document, string texte)
    {
        Word.Paragraph Object_Paragraphe;
        Object_Paragraphe = Object_Document.Content.Paragraphs.Add(Object_DontCare);
        Word.Range Object_Range = Object_Paragraphe.Range;
        Object_Range.Text = texte;
        Object_Range.set_Style(Microsoft.Office.Interop.Word.WdBuiltinStyle.wdStyleHeading1);
        Object_Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
        Object_Paragraphe.Range.InsertParagraphAfter();
    }
    /// <summary>
    /// Insérer un titre de style 2 dans un document Word en particulier.
    /// </summary>
    /// <param name="Object_Document">Document Word visé.</param>
    /// <param name="texte">Titre à insérer.</param>
    public void InsererTitreStyle2(Word.Document Object_Document, string texte)
    {
        Word.Paragraph Object_Paragraphe;
        Object_Paragraphe = Object_Document.Content.Paragraphs.Add(Object_DontCare);
        Word.Range Object_Range = Object_Paragraphe.Range;
        Object_Range.Text = texte;
        Object_Range.set_Style(Microsoft.Office.Interop.Word.WdBuiltinStyle.wdStyleHeading2);
        Object_Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
        Object_Paragraphe.Range.InsertParagraphAfter();
    }

    /// <summary>
    /// Enregistrement le rapport sous forme d'un PDF et ferme le document Word.
    /// </summary>
    /// <param name="Object_Application">Lien vers l'application Word.</param>
    /// <param name="Object_Document">Document Word visé</param>
    /// <param name="StringPath">Emplacement de sauvegarde du rapport. </param>
    /// <param name="StringNomRapport">Nom du fichier de rapport.</param>
    /// <param name="VarTypeDeRapport">Type de rapport.</param>
    public void SauvegardeEtQuitte(Word.Application Object_Application, Word.Document Object_Document, string StringPath, string StringNomRapport, string VarTypeDeRapport)
    {
        int i = 1;
        string VarDate = "_" + DateTime.Now.Year.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Day.ToString();

        if (File.Exists(StringPath + VarTypeDeRapport + "_" + StringNomRapport + VarDate + "_" + 1 + ".pdf"))
        {
            while (File.Exists(StringPath + VarTypeDeRapport + "_" + StringNomRapport + VarDate + "_" + i + ".pdf"))
                i++;
            Object_Document.SaveAs(FileName: StringPath + VarTypeDeRapport + "_" + StringNomRapport + VarDate + "_" + i, FileFormat: Word.WdSaveFormat.wdFormatPDF);
        }
        else
                Object_Document.SaveAs(FileName: StringPath + VarTypeDeRapport + "_" + StringNomRapport + VarDate + "_" + i, FileFormat: Word.WdSaveFormat.wdFormatPDF);
            

        Object_Document.Close(Word.WdSaveOptions.wdDoNotSaveChanges, Object_DontCare, Object_DontCare);
        Object_Application.Quit(Word.WdSaveOptions.wdDoNotSaveChanges, Object_DontCare, Object_DontCare);
    }

    /// <summary>
    /// Conversion du type de rapport
    /// </summary>
    /// <param name="type">Type de rapport sous la forme d'un chiffre</param>
    /// <returns>Type de rapport selon un type défini. </returns>
    public string TypeDeRapportEmploye(int type)
    {
        string VarTypeDeRapport = "Indef";
        switch (type)
	    {
            case  0:
                VarTypeDeRapport = "Hebdo";
            break;
            
            case  1:
                VarTypeDeRapport = "Periode";
            break;
            
            case  2:
                VarTypeDeRapport = "Complet";
            break;
            default:
        break;
	    }
        return VarTypeDeRapport;
    }
}
    
}
